define([
    'jQuery',
    'Underscore',
    'Backbone',
    'Kendo',
    'Gmaps',
    'i18n!nls/language',
    'models/tree',
    'datasources/tree',
    'datasources/treespecie',
    'datasources/soil',
    'datasources/location',
    'text!templates/tree/new.html'
], function($, 
            _, 
            Backbone, 
            Kendo, 
            Gmaps, 
            i18n, 
            Tree, 
            treeDatasource, 
            treespecieDatasource, 
            soilDatasource, 
            locationDatasource,
            treeNewTemplate) {

    
    var treeNewView = kendo.observable({
        
        // default values
        treespecies: treespecieDatasource,
        numberValue: 1,
        soils: soilDatasource,
        soilValue: 0,
        plantDateValue: Date.today(),
        heightValue: 20,
        diameterValue: 50,
        iconicValue: false,
        multitrunkValue: false,
        valuableValue: false,
        remark: '',
        
        map: new window.vta.geo(),
        
        locationJeroen: 'je stinkt, aap!',
        locationCurrent: null,
        locationCurrentText: '',
        locationManualText: '',
        locationPhotoText: '',
        
        uploadedPhoto: {},
        uploadedPhotoCounter: 0,
        
        label: i18n.tree.view.new,
        
        
        
        /**
         * function save
         * 
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       void
         * @return      Boolean false to prevent the default form action
         * 
         */
        save: function() {
console.clear();
            
            var location = null;
            var geoData = this.get('locationJeroen');
            var map = this.get("map");
            var treespecie = this.get("treespecieValue");
            var treespecieId = null;
            var treespecieName = "";
console.log(treespecie);
            if (typeof treespecie == "object") {
                treespecieId = treespecie.id;
                treespecieName = treespecie.latinname;
            }

            var soilId = this.get("soilValue");
            var plantDate = this.get("plantDateValue");
            var height = this.get("heightValue");
            var diameter = this.get("diameterValue");
            var iconic = this.get("iconicValue");
            var multitrunk = this.get("multitrunkValue");
            var valuable = this.get("valuableValue");
            var numberValue = this.get("numberValue");
            
            var treeData = {
                "treespecieId": treespecieId,
                "number": numberValue,
                "location": null,
                "soilId": soilId,
                "plantdate": plantDate,
                "stemdiameter": diameter,
                "height": height,
                "multitrunk": multitrunk,
                "valuable": valuable,
                "iconic": iconic
            };
            
console.log(geoData.geometry.location);  
console.log(geoData.geometry.location.lat());
console.log(geoData.geometry.location.lng());
            
            var locationData = {
                "longitude": geoData.geometry.location.lng(),
                "latitude": geoData.geometry.location.lat(),
                "street": map.parseLocation(geoData, 'route'),
                "city": map.parseLocation(geoData, 'locality'),
                "postalcode": map.parseLocation(geoData, 'postal_code'),
                "housenumber": map.parseLocation(geoData, 'street_number'),
                "housenumbersuffix": null,
                "country": map.parseLocation(geoData, 'country')
            };

            var deferredLocation = locationDatasource.create(locationData);
            var deferredTree = null;
            
            return deferredLocation.done(function(data){
                
                // the newly created and persisted model is available...
                location = data.models[0];
                
                // ... and, hey! the property id which has been added by the persistence with the database (back-end)
                // is available now... (and now I can do... whatever with it! :)
                console.log(location.id);
                
                treeData['location'] = location;
                
                deferredTree = treeDatasource.create(treeData);
                
//                return deferredTree.done(function(data) {
//                    
//                    var tree = data.models[0];
//                    
//                    console.log(tree);
//                    
//                    return tree;
//                    
//                });
                
                return deferredTree;
                
//                return location;
                
            });
            
            return false;
            
        },
        
        
        
        /**
         * function saveLocation
         * This will persist the location data to the back-end and will recieve a complete
         * Location location which will be returned (actually the promis will be returned).
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20121114
         * @param       void
         * @return      Location location
         * 
         */
        saveLocation: function() {

            var location = null;
            var geoData = this.get('locationJeroen');
            var map = this.get("map");       
            
            var locationData = {
                "longitude": geoData.geometry.location.Ya,
                "latitude": geoData.geometry.location.Za,
                "street": map.parseLocation(geoData, 'route'),
                "city": map.parseLocation(geoData, 'locality'),
                "postalcode": map.parseLocation(geoData, 'postal_code'),
                "housenumber": map.parseLocation(geoData, 'street_number'),
                "housenumbersuffix": null,
                "country": map.parseLocation(geoData, 'country')
            };

            var deferred = locationDatasource.create(locationData);
            
            return deferred.done(function(data){
                
                // the newly created and persisted model is available...
                location = data.models[0];
                
                // ... and, hey! the property id which has been added by the persistence with the database (back-end)
                // is available now... (and now I can do... whatever with it! :)
                console.log(location.id);
                
                return location;
                
            });
            
            // ... since this code normally executes, when it arrives overhere the property id still isn't available :'(
            console.log(location.id);
            
        },
        
        
        
        renderSubviews: function() {
            
            this.drawMap();
            this.determineCurrentLocation();
            
            $('.tooltip').tooltip();
            
//            $('#treespecieInfo').tooltip();
            
//            $('#treespecieInfo').mouseover( function() { alert("eppie"); } );
              
        },
        
        
        
        /**
         * function drawMap
         * Will draw the map onto the canvas div.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120917
         * @param       void
         * @return      void
         * 
         */
        drawMap: function() {
          
            this.get("map").createMap('map-canvas');
            
        },
        
        
        
        /**
         * function determineCurrentLocation
         * Will retrieve the current location from the map object.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       void
         * @return      void
         * 
         */
        determineCurrentLocation: function() {
          
            this.get("map").retrieveCurrentLocation({ text: this.setCurrentLocationRetrieved, marker: this.setMarkerLocationRetrieved }, true);
            
        },
        
        
        
        /**
         * function useManualLocation
         * Will set the current marker to the manual entered textual address.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       void
         * @return      void
         * 
         */
        useManualLocation: function(e) {
            
            e.preventDefault();
            
            var location = this.get("locationManualText");
            
            if (location.toString().trim().length == 0) {
                $('.top-right').notify({ message: { html: 'Er is (nog) geen handmatige locatie ingevoerd, doe dit eerst.' }, type: 'danger' }).show();
            } else {
                
                var map = this.get("map");
                
                var marker = map.getMarker('current');
                
                map.setMarkerLocationByAddress(location, marker, this.setManualLocationRetrieved);
                
            } // if (location.toString().trim().length == 0)
            
            
            
        },
        
        
        
        /**
         * function setManualLocationRetrieved
         * Will set the textual representation of the current location in the screen.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20121106
         * @param       String location
         * @return      void
         * 
         */
        setManualLocationRetrieved: function(location) {

            this.parent().setLocation(location);
            
        },
        
        
        
        /**
         * function setLocation
         * Contains the location object of the current selected location in the GUI.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20121030
         * @param       Object location
         * @return      void
         * 
         */
        setLocation: function(location) {

            this.set('locationJeroen', location);

        },
        
        
        
        /**
         * function setCurrentLocation
         * Contains the location object of the input in the GUI of the current location.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20121030
         * @param       Object location
         * @return      void
         * 
         */
        setCurrentLocation: function(location) {
            
            this.set('locationCurrent', location);
            
        },
        
        
        
        /**
         * function setCurrentLocationRetrieved
         * Will set the textual representation of the current location in the screen.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       String location
         * @return      void
         * 
         */
        setCurrentLocationRetrieved: function(location) {

            this.parent().setLocation(location);
            this.parent().setCurrentLocation(location);

            if (location.formatted_address.toString().trim().length > 0) {
                this.parent().set("locationCurrentText", location.formatted_address);
                this.parent().set("locationManualText", location.formatted_address);
            }

        },
        
        
        
        /**
         * function setMarkerLocationRetrieved
         * Callback on the dragend event of the current marker. Will update the textfield of the manual location.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20121008
         * @param       String location, the nearest address on which the marker has been placed by the user
         * @return      void
         * 
         */
        setMarkerLocationRetrieved: function(location) {

            this.parent().setLocation(location);

            this.parent().set("locationManualText", location.formatted_address);
            
        },
        
        
        
        /**
         * function useCurrentLocation
         * Will set the current marker to the address based on the current location of the device.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       void
         * @return      void
         * 
         */
        useCurrentLocation: function(e) {
alert('Kom ik soms hier?');
            e.preventDefault();
            
            this.setLocation(this.get('locationCurrent'));
            
            var location = this.get("locationCurrentText");

            if (location.toString().trim().length == 0) {
                $('.top-right').notify({ message: { html: 'Er is geen huidige locatie bepaald/ingevoerd, doe dit eerst.' }, type: 'danger' }).show();
            } else {
                
                var map = this.get("map");
                
                var marker = map.getMarker('current');
                
                map.setMarkerLocationByAddress(location, marker);
                
                this.set("locationManualText", location);
                
            }
            
            return false;
            
        },
        
        
        
        /**
         * function imageUpload
         * Eventhandler for asynchronous upload of images.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       event e
         * @return      void
         * 
         */
        imageUpload: function(e) {

            e.data = { fileDescription: $("#photos").val() };

        },
        
        
        
        /**
         * function imageUploadSuccess
         * Will add the nessecary form controls to a template and adds this template to the view and parses the bindings.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       event e
         * @return      void
         * 
         */
        imageUploadSuccess: function(e) {

            // set some default values
            var html = new Array();

            // get the counter and add one 
            var photoCounter = this.get("uploadedPhotoCounter");
            this.set("uploadedPhotoCounter", (photoCounter + 1));
            
            var photos = this.get("uploadedPhoto");
            photos[e.files[0].name] = e.files[0];
            
            if (e.response.result == true) {
                photos[e.files[0].name]['coords'] = e.response.data.coords;
                photos[e.files[0].name]['address'] = e.response.data.address;
                photos[e.files[0].name]['dimensions'] = e.response.data.dimensions;
                photos[e.files[0].name]['thumbnail'] = e.response.data.thumbnail;
                photos[e.files[0].name]['original'] = e.response.data.original;
            }
            
            this.set("uploadedPhoto", photos);

            // create the template for adding the location
            html.push('<div>');
              html.push('<table>');
                html.push('<tr>');
                  html.push('<td>');
                    html.push('<strong>'+ e.files[0].name +'</strong>');
                  html.push('</td>');
                  html.push('<td>');
                    html.push('<span class="imgPopover"><img class="uploaded-file" data-bind="events: { mouseover: showPhoto }" src="'+ e.response.data.thumbnail +'" /></span>');
                  html.push('</td>');
                  html.push('<td>');
//                    html.push('<div id="window'+ e.files[0].name +'"><img src="'+ e.response.data.original +'" /></div>');
                    html.push('&nbsp;');
                  html.push('</td>');
                html.push('</tr>');
                html.push('<tr>');
                  html.push('<td class="width-large" colspan="2">');
                    html.push(e.response.data.address);
                  html.push('</td>');
                  html.push('<td>');
                    html.push('<button class="k-button" id="'+ e.files[0].name +'" data-bind="click: usePhotoLocation"><i class="icon-screenshot"></i></button>');
                  html.push('</td>');
                html.push(' </tr>');
              html.push('</table>');
            html.push('</div>');
            

            // add the template to the current view and bind the events
            var template = Kendo.template(html.join(''));
            $("#photoData").append(template(this));
            
            Kendo.bind($("#photoData"), this);
            
        },
        
        
        
        /**
         * 
         * 
         */
        showPhoto: function(e) {
            
            console.log('showPhoto');
            console.log(e);
            console.log(e.target.attributes[0].value.toString().replace(/(\/upload\/)/gi, '').replace(/(_thumb)/gi,''))
            
            $('.imgPopover').popover({
                title: 'afbeelding: '+ e.target.attributes[0].value.toString().replace(/(\/upload\/)/gi, '').replace(/(_thumb)/gi,''),
                content: '<img src="'+ e.target.attributes[0].value.toString().replace(/(_thumb)/gi,'') +'">'
            });
            
          
        },
        
        
        
        /**
         * function usePhotoLocation
         * Will use the location as set by the image.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       event e
         * @return      Boolean false to prevent the default form action
         * 
         */
        usePhotoLocation: function(e) {
            
            var photoname = e.target.id;
            var photos = this.get("uploadedPhoto");
            
            for (var n in photos) {

                if (typeof photos[n] == "object" && photos[n].coords != undefined) {
              
                    // set the position on the map
                    var map = this.get("map");
                
                    var marker = map.getMarker('current');
                
                    map.setMarkerLocationByCoords(photos[n].coords.latitude, photos[n].coords.longitude, marker, this.setLocation);
                    
                    this.set("locationManualText", photos[n].address);
                    
                } // if (typeof photos[n] == "object" && photos[n].coords != undefined)
            
            } // for (var n in photos)


            // prevent the default behaviour a.k.a. POST the data
            return false;
            
        },
        
        
        
        /**
         * function showTooltip
         * Will call the function to show a tooltip on the current hovered object.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       void
         * @return      void
         * 
         */
        showTooltip: function(e) {
          
//            alert("laat die tooltip maar zien!");
            
//            console.log(e.target);
//            console.log(e.target.id);
            
//            $('#'+ e.target.id).tooltip();
            
        },
        
        
        
        /**
         * 
         * 
         * 
         */
        toggleExtendedControls: function(e) {
          
//            alert("Er is geklikt!");
            $('#extendedControls').toggle("slow");
        },
        
        
        
        /**
         * function toggleExtendedPosition
         * 
         */
        toggleExtendedPosition: function(e) {
            
            $('#extendedPosition').toggle("slow");
            
        },
        
        
        
        /**
         * function locationManualListener
         * Listener for the input-id locationManual.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       event e
         * @return      void
         * 
         */
        locationManualListener: function(e) {
            
            this.set("locationManualText", e.target.value);
            
        },
        
        
        
        /**
         * function locationCurrentListener
         * Listener for the input-id locationCurrent.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120925
         * @param       event e
         * @return      void
         *
         */
        locationCurrentListener: function(e) {
            
            this.set("locationCurrentText", e.target.value);
            
        },
        
        
        
        /**
         * function __construct
         * Constructor for the view.
         * 
         * @author      Jeroen Sen <jeroensen@22vision.nl>
         * @version     20120901
         * @param       this self
         * @param       Window window
         * @param       Variant Undefined
         * @return      void
         * 
         */
        __construct: (function(self, window, undefined) {
            
            // do nothing for now...
            
        })(this, window)
        
                
    });
    
    
    
    return treeNewView;
    
    
    
});